﻿using Google.Protobuf;
using JT809.DotNetty.Core.Clients;
using JT809.DotNetty.Core.Enums;
using JT809.DotNetty.Core.Handlers;
using JT809.DotNetty.Core.Interfaces;
using JT809.DotNetty.Core.Metadata;
using JT809.GrpcProtos;
using JT809.KafkaService;
using JT809.Protocol;
using JT809.Protocol.Enums;
using JT809.Protocol.Extensions;
using JT809.Protocol.MessageBody;
using JT809.Protocol.SubMessageBody;
using JT809.PubSub.Abstractions;
using JT809.Superior.Server.Configs;
using JT809.Superior.Server.Model;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using SqlSugar.IOC;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace JT809.Superior.Server
{
    public sealed class JT809SuperiorMsgIdReceiveHandler : JT809SuperiorMsgIdReceiveHandlerBase
    {
        private readonly JT809_GpsPositio_Producer producer;
        private readonly JT809GpsOptions gpsOptions;
        public JT809SuperiorMsgIdReceiveHandler(
            IOptions<JT809GpsOptions> jt809GpsAccessor,
            JT809_GpsPositio_Producer producer,
            ILoggerFactory loggerFactory,
            IJT809SubordinateLoginService jT809SubordinateLoginService,
            IJT809VerifyCodeGenerator verifyCodeGenerator)
            : base(loggerFactory, jT809SubordinateLoginService, verifyCodeGenerator)
        {
            this.producer = producer;
            this.gpsOptions = jt809GpsAccessor.Value;
        }

        public override JT809Response Msg0x1001(JT809Request request)
        {
            var verifyCode = VerifyCodeGenerator.Create();
            Logger.LogInformation($"主链路登录请求消息:VerifyCode-{verifyCode}");
            //Logger.LogInformation($"主链路登录请求消息:VerifyCode-0");

            var jT809_0x1001_header = request.Package.Header as JT809Header;
            var jT809_0x1001 = request.Package.Bodies as JT809_0x1001;

            var platform = DbScoped.SugarScope.Queryable<PlatformInfo>().Where(x => x.UserId == jT809_0x1001.UserId.ToString() && jT809_0x1001.Password == jT809_0x1001.Password && x.Status == 1).Single();

            JT809_0x1002_Result result = JT809_0x1002_Result.成功;

            if (platform == null)
            {
                result = JT809_0x1002_Result.密码错误;
            }
            else if (platform.MsgGNSSCENTERID != jT809_0x1001_header.MsgGNSSCENTERID)
            {
                result = JT809_0x1002_Result.接入码不正确;
            }
            else
            {
                SubordinateLoginService.Login(jT809_0x1001.DownLinkIP, jT809_0x1001.DownLinkPort);
            }

            var package = JT809BusinessType.主链路登录应答消息.Create(new JT809_0x1002()
            {
                Result = result,
                VerifyCode = verifyCode
            });
            package.Header.EncryptFlag = jT809_0x1001_header.EncryptFlag;
            package.Header.EncryptKey = jT809_0x1001_header.EncryptKey;

            //redis全局注册时使用
            var key = $"0x1001";
            RedisHelper.Set($"String:{key}:{jT809_0x1001.MsgGNSSCENTERID}", Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(jT809_0x1001)));
            RedisHelper.RPush($"List:{key}", JsonConvert.SerializeObject(jT809_0x1001));

            return new JT809Response(package, 100);
        }

        public override JT809Response Msg0x1200_0x1201(JT809Request request)
        {
            var exchangeMessageBodies = request.Package.Bodies as JT809ExchangeMessageBodies;
            var subBodies = exchangeMessageBodies.SubBodies as JT809_0x1200_0x1201;

            //redis全局注册时使用
            var key = $"0x1201";
            RedisHelper.Set($"String:{key}:{exchangeMessageBodies.VehicleNo}{exchangeMessageBodies.VehicleColor}", Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(subBodies)));
            RedisHelper.RPush($"List:{key}", JsonConvert.SerializeObject(subBodies));
            return base.Msg0x1200_0x1201(request);
        }

        public override JT809Response Msg0x1200_0x1202(JT809Request request)
        {
            var exchangeMessageBodies = request.Package.Bodies as JT809ExchangeMessageBodies;
            var gpsBodies = exchangeMessageBodies.SubBodies as JT809_0x1200_0x1202;
            JT809GpsPosition gpsPosition = new JT809GpsPosition();
            gpsPosition.Vno = exchangeMessageBodies.VehicleNo;
            gpsPosition.VColor = (byte)exchangeMessageBodies.VehicleColor;
            gpsPosition.Alarm = (int)gpsBodies.VehiclePosition.Alarm;
            gpsPosition.Altitude = gpsBodies.VehiclePosition.Altitude;
            gpsPosition.Direction = gpsBodies.VehiclePosition.Direction;
            gpsPosition.Encrypt = (byte)gpsBodies.VehiclePosition.Encrypt;
            gpsPosition.State = (int)gpsBodies.VehiclePosition.State;
            gpsPosition.Lat = gpsBodies.VehiclePosition.Lat;
            gpsPosition.Lon = gpsBodies.VehiclePosition.Lon;
            gpsPosition.Vec1 = gpsBodies.VehiclePosition.Vec1;
            gpsPosition.Vec2 = gpsBodies.VehiclePosition.Vec2;
            gpsPosition.Vec3 = (int)gpsBodies.VehiclePosition.Vec3;
            gpsPosition.GpsTime = (new DateTime(
                gpsBodies.VehiclePosition.Year,
                gpsBodies.VehiclePosition.Month,
                gpsBodies.VehiclePosition.Day,
                gpsBodies.VehiclePosition.Hour,
                gpsBodies.VehiclePosition.Minute,
                gpsBodies.VehiclePosition.Second).ToUniversalTime().Ticks - 621355968000000000) / 10000000;
            gpsPosition.FromChannel = gpsOptions.FromChannel;

            #region Kafka
            ////****二进制格式
            //producer.ProduceAsync($"{0x1202}", $"{exchangeMessageBodies.VehicleNo}{exchangeMessageBodies.VehicleColor}", Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(gpsPosition)));

            ////****protocol buffers格式
            //producer.ProduceAsync($"{0x1202}", $"{exchangeMessageBodies.VehicleNo}{exchangeMessageBodies.VehicleColor}", gpsPosition.ToByteArray());
            #endregion

            #region Redis
            //redis全局注册时使用
            var key = $"0x1202";
            RedisHelper.Set($"String:{key}:{exchangeMessageBodies.VehicleNo}{exchangeMessageBodies.VehicleColor}", gpsPosition.ToByteArray());
            RedisHelper.RPush($"List:{key}", JsonConvert.SerializeObject(gpsPosition));
            #endregion

            //using (StreamWriter sw = new StreamWriter("gps.txt", true))
            //{
            //    sw.WriteLine($"{0x1202}" + " " + $"{exchangeMessageBodies.VehicleNo}{exchangeMessageBodies.VehicleColor}" + " " + Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(gpsPosition)));
            //}
            return base.Msg0x1200_0x1202(request);
        }

        public override JT809Response Msg0x1200_0x1203(JT809Request request)
        {
            var exchangeMessageBodies = request.Package.Bodies as JT809ExchangeMessageBodies;
            var gpsBodies = exchangeMessageBodies.SubBodies as JT809_0x1200_0x1203;

            if (gpsBodies.GNSSCount > 0)
            {
                foreach (JT809_0x1200_0x1202 gpsBodie in gpsBodies.GNSS)
                {
                    JT809GpsPosition gpsPosition = new JT809GpsPosition();
                    gpsPosition.Vno = exchangeMessageBodies.VehicleNo;
                    gpsPosition.VColor = (byte)exchangeMessageBodies.VehicleColor;
                    gpsPosition.Alarm = (int)gpsBodie.VehiclePosition.Alarm;
                    gpsPosition.Altitude = gpsBodie.VehiclePosition.Altitude;
                    gpsPosition.Direction = gpsBodie.VehiclePosition.Direction;
                    gpsPosition.Encrypt = (byte)gpsBodie.VehiclePosition.Encrypt;
                    gpsPosition.State = (int)gpsBodie.VehiclePosition.State;
                    gpsPosition.Lat = gpsBodie.VehiclePosition.Lat;
                    gpsPosition.Lon = gpsBodie.VehiclePosition.Lon;
                    gpsPosition.Vec1 = gpsBodie.VehiclePosition.Vec1;
                    gpsPosition.Vec2 = gpsBodie.VehiclePosition.Vec2;
                    gpsPosition.Vec3 = (int)gpsBodie.VehiclePosition.Vec3;
                    gpsPosition.GpsTime = (new DateTime(
                        gpsBodie.VehiclePosition.Year,
                        gpsBodie.VehiclePosition.Month,
                        gpsBodie.VehiclePosition.Day,
                        gpsBodie.VehiclePosition.Hour,
                        gpsBodie.VehiclePosition.Minute,
                        gpsBodie.VehiclePosition.Second).ToUniversalTime().Ticks - 621355968000000000) / 10000000;
                    gpsPosition.FromChannel = gpsOptions.FromChannel;

                    #region Kafka
                    //***kafka***二进制
                    //producer.ProduceAsync($"{0x1202}", $"{exchangeMessageBodies.VehicleNo}{exchangeMessageBodies.VehicleColor}", Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(gpsPosition)));

                    //***kafka***protocolbuffer
                    //producer.ProduceAsync($"{0x1202}", $"{exchangeMessageBodies.VehicleNo}{exchangeMessageBodies.VehicleColor}", gpsPosition.ToByteArray());
                    #endregion

                    #region Redis
                    //redis全局注册时使用
                    var key = $"0x1203";
                    RedisHelper.Set($"String:{key}:{exchangeMessageBodies.VehicleNo}{exchangeMessageBodies.VehicleColor}", gpsPosition.ToByteArray());
                    RedisHelper.RPush($"List:{key}", JsonConvert.SerializeObject(gpsPosition));
                    #endregion
                }
            }
            return base.Msg0x1200_0x1203(request);
        }

        public override JT809Response Msg0x1200_0x120C(JT809Request request)
        {
            var exchangeMessageBodies = request.Package.Bodies as JT809ExchangeMessageBodies;
            var subBodies = exchangeMessageBodies.SubBodies as JT809_0x1200_0x120C;

            //redis全局注册时使用
            var key = $"0x120C";
            RedisHelper.Set($"String:{key}:{exchangeMessageBodies.VehicleNo}{exchangeMessageBodies.VehicleColor}", Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(subBodies)));
            RedisHelper.RPush($"List:{key}", JsonConvert.SerializeObject(subBodies));
            return base.Msg0x1200_0x120C(request);
        }

        public override JT809Response Msg0x1200_0x120D(JT809Request request)
        {
            var exchangeMessageBodies = request.Package.Bodies as JT809ExchangeMessageBodies;
            var subBodies = exchangeMessageBodies.SubBodies as JT809_0x1200_0x120D;

            //redis全局注册时使用
            var key = $"0x120D";
            RedisHelper.Set($"String:{key}:{exchangeMessageBodies.VehicleNo}{exchangeMessageBodies.VehicleColor}", Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(subBodies)));
            RedisHelper.RPush($"List:{key}", JsonConvert.SerializeObject(subBodies));
            return base.Msg0x1200_0x120D(request);
        }

        public override JT809Response Msg0x1200_0x120E(JT809Request request)
        {
            var exchangeMessageBodies = request.Package.Bodies as JT809ExchangeMessageBodies;
            var subBodies = exchangeMessageBodies.SubBodies as JT809_0x1200_0x120E;

            //redis全局注册时使用
            var key = $"0x120E";
            RedisHelper.Set($"String:{key}:{exchangeMessageBodies.VehicleNo}{exchangeMessageBodies.VehicleColor}", Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(subBodies)));
            RedisHelper.RPush($"List:{key}", JsonConvert.SerializeObject(subBodies));
            return base.Msg0x1200_0x120E(request);
        }
    }
}
